{"componentChunkName":"component---src-templates-blog-post-js","path":"/2019/05/05/搭建-gatsby-博客四：兼容 Jekyll 式路径/","result":{"data":{"site":{"siteMetadata":{"title":"CHENHUOJUN BLOG"}},"post":{"id":"3cc52b1f-872a-54cd-bd66-c5cbc6418402","html":"<p>迁移博客需要考虑的一个重要问题便是路径兼容。我们当然不希望迁移后原有的链接无法访问，这不仅影响到 SEO ，更带来了不好的用户访问体验。本文将聊聊怎么让 Gatsby 兼容 Jekyll 式路径。</p>\n<h2 id=\"gatsby-如何生成特定页面\" style=\"position:relative;\"><a href=\"#gatsby-%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90%E7%89%B9%E5%AE%9A%E9%A1%B5%E9%9D%A2\" aria-label=\"gatsby 如何生成特定页面 permalink\" class=\"auto-anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Gatsby 如何生成特定页面</h2>\n<p>一般来说，在 <code>/src/pages/</code> 目录下的组件会自动生成相应路径的页面，但如果是其它类型的文件就不会了。我们可以通过 Gatsby 的 Node APIs 来生成特定页面。</p>\n<p>在 <code>/gatsby-node.js</code> 中配置 Gatsby Node APIs，如果项目是基于 starter 的话你很可能会发现里面已经有相应的配置。</p>\n<p>我们通过声明 <code>exports.createPages</code> 钩子来配置页面生成，在回调中通过调用 <code>actions.createPage</code> 来生成某个指定页面。这个方法接受一个配置参数，其中的 <code>path</code> 域代表了生成页面的路径。</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-javascript line-numbers\"><code class=\"language-javascript\">exports<span class=\"token punctuation\">.</span><span class=\"token function-variable function\">createPages</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> actions<span class=\"token punctuation\">,</span> graphql <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  actions<span class=\"token punctuation\">.</span><span class=\"token function\">createPage</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n    path<span class=\"token punctuation\">,</span>\n    <span class=\"token comment\">// ...</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<h2 id=\"指定博客页面\" style=\"position:relative;\"><a href=\"#%E6%8C%87%E5%AE%9A%E5%8D%9A%E5%AE%A2%E9%A1%B5%E9%9D%A2\" aria-label=\"指定博客页面 permalink\" class=\"auto-anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>指定博客页面</h2>\n<p>那么我们怎么知道该生成哪些页面呢？这里通过 <code>exports.createPages</code> 回调中的 <code>graphql</code> 来查询 Markdown 文件。</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-javascript line-numbers\"><code class=\"language-javascript\">exports<span class=\"token punctuation\">.</span><span class=\"token function-variable function\">createPages</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> actions<span class=\"token punctuation\">,</span> graphql <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> createPage <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> actions\n\n  <span class=\"token keyword\">return</span> <span class=\"token function\">graphql</span><span class=\"token punctuation\">(</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">\n    {\n      allMarkdownRemark(sort: { order: ASC, fields: [frontmatter___date] }) {\n        edges {\n          node {\n            id\n            fields {\n              slug\n            }\n            frontmatter {\n              path\n              title\n              layout\n            }\n          }\n        }\n      }\n    }\n  </span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">result</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>result<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      result<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">.</span><span class=\"token function\">forEach</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span> <span class=\"token operator\">=></span> console<span class=\"token punctuation\">.</span><span class=\"token function\">error</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span><span class=\"token function\">toString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token keyword\">return</span> Promise<span class=\"token punctuation\">.</span><span class=\"token function\">reject</span><span class=\"token punctuation\">(</span>result<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n    \n    <span class=\"token comment\">// ...</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>Netlify CMS 会在 Markdown front matters 中的 <code>path</code> 域生成路径。根据默认的 <code>/static/admin/config.yml</code> 我们的路径应该是 <code>/blog/{{year}}-{{month}}-{{day}}-{{slug}}/</code>，这个可能跟旧博客不一样，如 Jekyll 是 <code>/{{year}}/{{month}}/{{day}}/{{slug}}/</code>。</p>\n<h2 id=\"修改-markdown-节点\" style=\"position:relative;\"><a href=\"#%E4%BF%AE%E6%94%B9-markdown-%E8%8A%82%E7%82%B9\" aria-label=\"修改 markdown 节点 permalink\" class=\"auto-anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>修改 Markdown 节点</h2>\n<p>在 Remark 插件生成的 Markdown 节点中，我们可以往 <code>fields</code> 域放一些自定义的变量。这里我们把自定义的路径存到 <code>fields.slug</code> 中。</p>\n<p>通过 <code>/gatsby-node.js</code> 中的 <code>exports.onCreateNode</code> 钩子我们可以在生成节点的时候进行拦截处理。你可能发现文件里面已经有一些配置的代码了，我们这里只关注 Markdown 相关的。</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-javascript line-numbers\"><code class=\"language-javascript\">exports<span class=\"token punctuation\">.</span><span class=\"token function-variable function\">onCreateNode</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> node<span class=\"token punctuation\">,</span> actions<span class=\"token punctuation\">,</span> getNode <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> createNodeField <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> actions\n\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>node<span class=\"token punctuation\">.</span>internal<span class=\"token punctuation\">.</span>type <span class=\"token operator\">===</span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">MarkdownRemark</span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// Jeykll style post path</span>\n    <span class=\"token keyword\">const</span> filepath <span class=\"token operator\">=</span> <span class=\"token function\">createFilePath</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> node<span class=\"token punctuation\">,</span> getNode <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n    <span class=\"token function\">createNodeField</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n      node<span class=\"token punctuation\">,</span>\n      name<span class=\"token operator\">:</span> <span class=\"token string\">'slug'</span><span class=\"token punctuation\">,</span>\n      value<span class=\"token operator\">:</span> filepath<span class=\"token punctuation\">.</span><span class=\"token function\">replace</span><span class=\"token punctuation\">(</span>\n        <span class=\"token regex\">/^\\/blog\\/([\\d]{4})-([\\d]{2})-([\\d]{2})-/</span><span class=\"token punctuation\">,</span>\n        <span class=\"token string\">'/$1/$2/$3/'</span>\n      <span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>我们把原有的路径值换成了自定义值并存在了 <code>fileds.slug</code> 中。</p>\n<h2 id=\"创建页面\" style=\"position:relative;\"><a href=\"#%E5%88%9B%E5%BB%BA%E9%A1%B5%E9%9D%A2\" aria-label=\"创建页面 permalink\" class=\"auto-anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>创建页面</h2>\n<p>得到需要的数据之后只需要对每个页面调用 <code>actions.createPage</code> 即可。</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-javascript line-numbers\"><code class=\"language-javascript\">exports<span class=\"token punctuation\">.</span><span class=\"token function-variable function\">createPages</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> actions<span class=\"token punctuation\">,</span> graphql <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> createPage <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> actions\n\n  <span class=\"token keyword\">return</span> <span class=\"token function\">graphql</span><span class=\"token punctuation\">(</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">\n    {\n      allMarkdownRemark(sort: { order: ASC, fields: [frontmatter___date] }) {\n        edges {\n          node {\n            id\n            fields {\n              slug\n            }\n            frontmatter {\n              path\n              title\n              layout\n            }\n          }\n        }\n      }\n    }\n  </span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">result</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>result<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      result<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">.</span><span class=\"token function\">forEach</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span> <span class=\"token operator\">=></span> console<span class=\"token punctuation\">.</span><span class=\"token function\">error</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span><span class=\"token function\">toString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token keyword\">return</span> Promise<span class=\"token punctuation\">.</span><span class=\"token function\">reject</span><span class=\"token punctuation\">(</span>result<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n    \n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> edges <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> result<span class=\"token punctuation\">.</span>data<span class=\"token punctuation\">.</span>allMarkdownRemark\n\n    <span class=\"token keyword\">const</span> options <span class=\"token operator\">=</span> edges<span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">edge</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n      path<span class=\"token operator\">:</span> edge<span class=\"token punctuation\">.</span>node<span class=\"token punctuation\">.</span>fields<span class=\"token punctuation\">.</span>slug<span class=\"token punctuation\">,</span>\n      title<span class=\"token operator\">:</span> edge<span class=\"token punctuation\">.</span>node<span class=\"token punctuation\">.</span>frontmatter<span class=\"token punctuation\">.</span>title<span class=\"token punctuation\">,</span>\n      component<span class=\"token operator\">:</span> path<span class=\"token punctuation\">.</span><span class=\"token function\">resolve</span><span class=\"token punctuation\">(</span>\n        <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">src/templates/</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>edge<span class=\"token punctuation\">.</span>node<span class=\"token punctuation\">.</span>frontmatter<span class=\"token punctuation\">.</span>layout<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">.js</span><span class=\"token template-punctuation string\">`</span></span>\n      <span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n      <span class=\"token comment\">// additional data can be passed via context</span>\n      context<span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n        id<span class=\"token operator\">:</span> edge<span class=\"token punctuation\">.</span>node<span class=\"token punctuation\">.</span>id\n      <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    \n    options<span class=\"token punctuation\">.</span><span class=\"token function\">forEach</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">option</span> <span class=\"token operator\">=></span> <span class=\"token function\">createPage</span><span class=\"token punctuation\">(</span>option<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>也许你会问为什么不在这里直接计算自定义路径而是要存到 <code>fields.slug</code> 中。这是因为这个路径我们可能还会在其它地方用到，存起来就不必多处计算了。</p>\n<p>上面代码中可以注意到还有个 <code>context</code> 域，这个域中的数据会被传到 <code>component</code> 的 props 中。这样我们在模板组件中通过 <code>pageContext.id</code> 便可判断当前渲染的文件。</p>\n<p>通过实现自定义路径基本上可以了解 Gatsby 页面生成的方式了。下篇文章中我会继续谈谈其它个性化的配置，如草稿模式和显示上下篇博文。</p>","excerpt":"迁移博客需要考虑的一个重要问题便是路径兼容。我们当然不希望迁移后原有的链接无法访问，这不仅影响到 SEO ，更带来了不好的用户访问体验。本文将聊聊怎么让 Gatsby 兼容 Jekyll 式路径。 Gatsby 如何生成特定页面 一般来说，在 /src/pages/ 目录下的组件会自动生成相应路径的页面，但如果是其它类型的文件就不会了。我们可以通过 Gatsby 的 Node APIs…","tableOfContents":"<ul>\n<li><a href=\"/2019/05/05/%E6%90%AD%E5%BB%BA-gatsby-%E5%8D%9A%E5%AE%A2%E5%9B%9B%EF%BC%9A%E5%85%BC%E5%AE%B9%20Jekyll%20%E5%BC%8F%E8%B7%AF%E5%BE%84/#gatsby-%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90%E7%89%B9%E5%AE%9A%E9%A1%B5%E9%9D%A2\">Gatsby 如何生成特定页面</a></li>\n<li><a href=\"/2019/05/05/%E6%90%AD%E5%BB%BA-gatsby-%E5%8D%9A%E5%AE%A2%E5%9B%9B%EF%BC%9A%E5%85%BC%E5%AE%B9%20Jekyll%20%E5%BC%8F%E8%B7%AF%E5%BE%84/#%E6%8C%87%E5%AE%9A%E5%8D%9A%E5%AE%A2%E9%A1%B5%E9%9D%A2\">指定博客页面</a></li>\n<li><a href=\"/2019/05/05/%E6%90%AD%E5%BB%BA-gatsby-%E5%8D%9A%E5%AE%A2%E5%9B%9B%EF%BC%9A%E5%85%BC%E5%AE%B9%20Jekyll%20%E5%BC%8F%E8%B7%AF%E5%BE%84/#%E4%BF%AE%E6%94%B9-markdown-%E8%8A%82%E7%82%B9\">修改 Markdown 节点</a></li>\n<li><a href=\"/2019/05/05/%E6%90%AD%E5%BB%BA-gatsby-%E5%8D%9A%E5%AE%A2%E5%9B%9B%EF%BC%9A%E5%85%BC%E5%AE%B9%20Jekyll%20%E5%BC%8F%E8%B7%AF%E5%BE%84/#%E5%88%9B%E5%BB%BA%E9%A1%B5%E9%9D%A2\">创建页面</a></li>\n</ul>","fields":{"slug":"/2019/05/05/搭建-gatsby-博客四：兼容 Jekyll 式路径/"},"frontmatter":{"date":"May 05, 2019","title":"搭建 Gatsby 博客四：兼容 Jekyll 式路径","description":"前面已经让博客顺利运行起来，接下来就是实现一些个性化的功能。本文通过实现兼容 Jekyll 式路径来了解 Gatsby 的 Node APIs。","quote":{"content":"\"Do not go where the path may lead, go instead where there is no path and leave a trail.\" ","author":"Ralph Waldo Emerson","source":""},"tags":["Gatsby","Blog","Jekyll"]}}},"pageContext":{"id":"3cc52b1f-872a-54cd-bd66-c5cbc6418402","prev":{"title":"搭建 Gatsby 博客三：使用 Netlify CMS 管理文章","path":"/2019/04/26/搭建-gatsby-博客三：使用-netlify-cms-管理文章/"},"next":{"title":"搭建 Gatsby 博客五：实现草稿模式和上下篇","path":"/2019/05/13/搭建-gatsby-博客五：实现草稿模式和上下篇/"}}}}